home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / constmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-15  |  2.3 KB  |  124 lines

  1. #include "constmap.h"
  2. #include "alloc.h"
  3. #include "case.h"
  4.  
  5. static constmap_hash hash(s,len)
  6. char *s;
  7. int len;
  8. {
  9.  unsigned char ch;
  10.  constmap_hash h;
  11.  h = 5381;
  12.  while (len > 0)
  13.   {
  14.    ch = *s++ - 'A';
  15.    if (ch <= 'Z' - 'A') ch += 'a' - 'A';
  16.    h = ((h << 5) + h) ^ ch;
  17.    --len;
  18.   }
  19.  return h;
  20. }
  21.  
  22. char *constmap(cm,s,len)
  23. struct constmap *cm;
  24. char *s;
  25. int len;
  26. {
  27.  constmap_hash h;
  28.  int pos;
  29.  h = hash(s,len);
  30.  pos = cm->first[h & cm->mask];
  31.  while (pos != -1)
  32.   {
  33.    if (h == cm->hash[pos])
  34.      if (len == cm->inputlen[pos])
  35.        if (!case_diffb(cm->input[pos],len,s))
  36.      return cm->input[pos] + cm->inputlen[pos] + 1;
  37.    pos = cm->next[pos];
  38.   }
  39.  return 0;
  40. }
  41.  
  42. int constmap_init(cm,s,len,flagcolon)
  43. struct constmap *cm;
  44. char *s;
  45. int len;
  46. int flagcolon;
  47. {
  48.  int i;
  49.  int j;
  50.  int k;
  51.  int pos;
  52.  constmap_hash h;
  53.  
  54.  cm->num = 0;
  55.  for (j = 0;j < len;++j) if (!s[j]) ++cm->num;
  56.  
  57.  h = 64;
  58.  while (h && (h < cm->num)) h += h;
  59.  cm->mask = h - 1;
  60.  
  61.  cm->first = (int *) alloc(sizeof(int) * h);
  62.  if (cm->first)
  63.   {
  64.    cm->input = (char **) alloc(sizeof(char *) * cm->num);
  65.    if (cm->input)
  66.     {
  67.      cm->inputlen = (int *) alloc(sizeof(int) * cm->num);
  68.      if (cm->inputlen)
  69.       {
  70.        cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num);
  71.        if (cm->hash)
  72.     {
  73.      cm->next = (int *) alloc(sizeof(int) * cm->num);
  74.      if (cm->next)
  75.       {
  76.        for (h = 0;h <= cm->mask;++h)
  77.          cm->first[h] = -1;
  78.            pos = 0;
  79.            i = 0;
  80.            for (j = 0;j < len;++j)
  81.              if (!s[j])
  82.               {
  83.            k = j - i;
  84.            if (flagcolon)
  85.         {
  86.          for (k = i;k < j;++k)
  87.            if (s[k] == ':')
  88.              break;
  89.          if (k >= j) { i = j + 1; continue; }
  90.          k -= i;
  91.         }
  92.                cm->input[pos] = s + i;
  93.                cm->inputlen[pos] = k;
  94.                h = hash(s + i,k);
  95.                cm->hash[pos] = h;
  96.                h &= cm->mask;
  97.                cm->next[pos] = cm->first[h];
  98.                cm->first[h] = pos;
  99.                ++pos;
  100.                i = j + 1;
  101.               }
  102.            return 1;
  103.       }
  104.      alloc_free(cm->hash);
  105.     }
  106.        alloc_free(cm->inputlen);
  107.       }
  108.      alloc_free(cm->input);
  109.     }
  110.    alloc_free(cm->first);
  111.   }
  112.  return 0;
  113. }
  114.  
  115. void constmap_free(cm)
  116. struct constmap *cm;
  117. {
  118.  alloc_free(cm->next);
  119.  alloc_free(cm->hash);
  120.  alloc_free(cm->inputlen);
  121.  alloc_free(cm->input);
  122.  alloc_free(cm->first);
  123. }
  124.